<template>
  <div class="table-page" :style="`width:${width}`">
    <div class="handle-slot" style="padding: 20px 30px">
      <slot name="handle" />
    </div>
    <el-table
      ref="table"
      :data="tableData"
      :border="border"
      :height="height"
      :row-key="customGetRowKey ? customGetRowKey : getRowKey"
      :header-cell-class-name="cellClass"
      @sort-change="sortChange"
      @selection-change="handleSelectionChange"
      @current-change="handleActiveCurrent"
      @select="handleSelect"
    >
      <slot />
      <el-table-column
        v-if="isSelection"
        :key="1"
        width="50"
        type="selection"
        align="center"
        :selectable="selectable"
        :disabled="false"
        :reserve-selection="true"
      />
      <el-table-column
        v-if="isIndex"
        type="index"
        label="序号"
        :width="indexWidth"
        :align="indexAlign"
        :fixed="indexFixed"
      />
      <!-- 自定义star表头 -->
      <el-table-column v-if="isStar" prop="star" width="60" :render-header="starRender">
        <template slot-scope="scope">
          <i :class="`el-icon-star-on ${scope['row']['star'] ? 'on' : 'off'}`" />
        </template>
      </el-table-column>

      <template v-for="(item, _index) in tableColumn">
        <el-table-column
          v-if="!item.policy || checkPermission(item.policy)"
          :key="_index + 2"
          :label="item.label"
          :prop="item.prop"
          :width="item.width || minWidth"
          :align="item.align ? item.align : align"
          :sort-by="item.prop"
          :sortable="item.sortable ? item.sortable : false"
          :sort-orders="['ascending', 'descending', null]"
          :show-overflow-tooltip="item.hideTooLtip ? false : true"
          :fixed="item.fixed || false"
        >
          <template slot-scope="scope">
            <slot v-if="item.render ? item.render : false" v-bind="scope" :name="item.prop" />

            <!-- switch -->
            <div v-else-if="item.type == 'switch'">
              <el-switch v-model="scope.row[item.prop]" />
            </div>

            <!-- 带圆点 -->
            <div v-else-if="item.type == 'yuanText'">
              <span
                :class="['circle', `circle_${item.prop}`]"
                :style="{
                  backgroundColor: (() => {
                    const $value = scope.row[item['by'] || item.prop],
                      target = item.colors ? item.colors.find((i) => i['value'] == $value) : {}
                    return target && target['color']
                  })()
                }"
              />
              {{ isTdText(scope, item) }}
            </div>

            <!-- 链接 -->
            <div v-else-if="item.type == 'linkText'">
              <el-link :class="['link', `link_${item.prop}`]" href="javascript:;" target="_blank">
                {{ isTdText(scope, item) }}
              </el-link>
            </div>

            <!-- 带颜色 -->
            <div
              v-else-if="item.type == 'color'"
              :style="{
                color: (() => {
                  const $value = scope.row[item.prop],
                    target = item.colors.find((i) => i['value'] == $value)
                  return target && target['color']
                })()
              }"
            >
              {{ isTdText(scope, item) }}
            </div>

            <div v-else-if="item.type === 'button'">
              <span v-for="(btn, index) in item.buttons" :key="index">
                <el-button
                  v-if="!btn.policy || checkPermission(btn.policy)"
                  v-show="btn.hide ? (btn.hideValue.indexOf(scope.row[btn.hide]) === -1 ? false : true) : true"
                  :class="`button-text ${item.class || ''} button-span`"
                  :size="size"
                  :disabled="btn.limit ? (btn.limitValue == scope.row[_item.limit] ? false : true) : false"
                  :type="btn.type || 'text'"
                  @click="
                    (e) => {
                      labelMethod(e, btn.method || item.method[index], scope.row, btn)
                    }
                  "
                >
                  <span :class="`${btn.class || ''}`" :style="`color: ${btn.color || ''}`">{{ btn.label }}</span>
                </el-button>
              </span>
            </div>
            <div v-else-if="item.type === 'roleButton'">
              <span v-for="(btn, index) in item.buttons" :key="index">
                <el-button
                  v-if="!btn.policy || checkPermission(btn.policy)"
                  v-show="!(btn.hide && btn.hideValue.includes(scope.row[btn.hide]))"
                  :class="`button-text ${item.class || ''} button-span`"
                  :size="size"
                  :disabled="btn.limit ? (btn.limitValue == scope.row[_item.limit] ? false : true) : false"
                  :type="btn.type || 'text'"
                  @click="
                    (e) => {
                      labelMethod(e, btn.method || item.method[index], scope.row, btn)
                    }
                  "
                >
                  <span :class="`${btn.class || ''}`" :style="`color: ${btn.color || ''}`">{{ btn.label }}</span>
                </el-button>
              </span>
            </div>
            <!-- 文本 -->
            <div v-else>
              {{ isTdText(scope, item) }}
            </div>
          </template>
        </el-table-column>
      </template>
    </el-table>
    <el-pagination
      v-if="isPage"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
      :page-size="pageSize"
      :current-page="currentPage"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
  </div>
</template>

<script>
import { checkPermission } from '@/utils/central'

export default {
  name: 'TablePage',
  props: {
    tableColumn: {
      type: Array,
      default: () => []
    },
    tableData: {
      type: Array,
      default: () => []
    },
    width: {
      type: String,
      default: 'auto'
    },
    height: {
      type: [Number, String],
      default: undefined
    },
    indexAlign: {
      type: String,
      default: 'center'
    },
    indexWidth: {
      type: Number,
      default: 80
    },
    // 表格列最小宽度
    minWidth: {
      type: [Number, String],
      default: 'auto'
    },
    maxHeight: {
      type: [Number, String],
      default: undefined
    },
    isIndex: {
      type: Boolean,
      default: true
    },
    isStar: {
      type: Boolean,
      default: false
    },
    isSelection: {
      type: Boolean,
      default: false
    },
    isPage: {
      type: Boolean,
      default: true
    },
    total: {
      type: Number,
      default: 0
    },
    pageSize: {
      type: Number,
      default: 10
    },
    currentPage: {
      type: Number,
      default: 1
    },
    size: {
      type: String,
      default: ''
    },
    align: {
      type: String,
      default: 'left'
    },
    border: {
      type: Boolean,
      default: false
    },
    selectable: {
      type: Function,
      default: () => {
        return true
      }
    },
    // 是否单选
    isSingle: {
      type: Boolean,
      default: false
    },
    indexFixed: {
      type: [Boolean, String],
      default: false
    },
    // 自定义getRowKey
    customGetRowKey: {
      type: Function
    }
  },
  data: function () {
    return {}
  },
  data: function () {
    return {
      selections: []
    }
  },
  computed: {
    isTdText: function () {
      return (scope, item) => {
        if (scope.row[item.prop] == null || scope.row[item.prop] == undefined) return '-'
        return item.dicts && Array.isArray(item.dicts)
          ? this.dictLabel(item.dicts, scope.row[item.prop])
          : `${scope.row[item.prop]}${item.unit || ''}`
      }
    }
  },
  methods: {
    checkPermission,
    cellClass(row) {
      if (row.columnIndex === 0 && this.isSingle) {
        return 'disableheadselection'
      }
    },
    getRowKey(row) {
      return row.id
    },
    starRender(h, { column }) {
      return h('span', [h('i', { class: 'el-icon-star-on off' })])
    },
    dictLabel(options, value, KEY = 'label') {
      if (!options instanceof Array || !options.length) return ''
      try {
        return Array.isArray(value)
          ? value.map((i) => options.find((j) => j['value'] === i)[KEY]).join()
          : options.find((i) => i['value'] === value)[KEY]
      } catch (error) {}
    },
    sortChange(val) {
      const sort = {
        ...val,
        order: val.order === 'ascending' ? 'ASC' : val.order === 'descending' ? 'DESC' : ''
      }
      this.$emit('handleSortChange', sort)
    },
    handleSelect(selection, row) {
      this.$emit('handleSelect', { selection, row })
    },
    handleSelectionChange(v) {
      if (this.isSingle) {
        this.$emit('handleSelectionChange', this.handleSingleSelect(v))
      } else {
        this.$emit('handleSelectionChange', v)
      }
    },
    handleSizeChange(value) {
      this.pageSize = value
      this.$emit('sizeChange', value)
    },
    handleActiveCurrent(value) {
      this.$emit('activeCurrent', value)
    },
    handleCurrentChange(value) {
      this.$emit('currentChange', value)
    },
    labelMethod(e, v, row, item) {
      if (item.stop) e.stopPropagation()
      this.$bus.$emit(v, row)
    },
    clearSelection() {
      this.$refs.table.clearSelection()
    },
    toggleRowSelection(row, selected) {
      this.$refs.table.toggleRowSelection(row, selected)
    },
    handleSingleSelect(selection) {
      let selections = []
      if (selection.length > 1) {
        this.$refs.table.clearSelection()
        this.$refs.table.toggleRowSelection(selection[selection.length - 1])
      }
      selections = [selection[selection.length - 1]]
      return selections
    }
  }
}
</script>

<style lang="scss" scoped>
::v-deep.table-page {
  .el-table {
    width: 100%;
    th > .cell,
    td > .cell {
      padding: 0 15px;
      box-sizing: border-box;
      line-height: auto;
      div {
        overflow: hidden;
        text-overflow: ellipsis;
      }
    }
    th {
      background: $table_header_bg;
      font-size: 14px;
      color: #404040;
      padding: 12px 0px;
      box-sizing: border-box;
    }
    td {
      border-bottom: 1px solid #e8e8e8;
      padding: 12px 0px;
      box-sizing: border-box;
      font-size: 14px;
      color: #333333;
      .el-button {
        padding: 0 2px;
        font-weight: initial;
      }
      span.circle {
        display: inline-block;
        width: 7px;
        height: 7px;
        margin-right: 6px;
        border-radius: 100%;
        background: #33ee46;
      }

      .link {
        color: #0076ff;
        cursor: pointer;
      }
    }
  }
  .el-pagination {
    height: 50px;
    display: flex;
    margin: 10px 20px;
    align-items: center;
    justify-content: flex-end;
  }
  .button-text {
    margin-right: 5px;
  }
  .handle-slot:empty {
    padding: 0 !important;
  }
  .el-icon-star-on {
    font-size: 0.28rem;
    &.on {
      color: rgba(255, 96, 88, 1);
    }
    &.off {
      color: rgba(221, 221, 221, 1);
    }
  }
}
::v-deep .disableheadselection > .cell .el-checkbox__inner {
  display: none;
}
.el-pagination {
  white-space: nowrap;
  padding: 2px 0.28rem;
  color: #606266;
  font-weight: normal;
}
</style>
